#!/bin/bash
#pMusic - Masstagger
#GPL - Copyright Sigmund Berglund

. $APPDIR/func -reset_gtk
export TEXTDOMAIN=pmusic
export OUTPUT_CHARSET=UTF-8
export ID3_GENRES=`awk -F "(" '{print "<item>"$1"("$2"</item>"}' $APPDIR/txt_id3genre` #build id3 genres

info(){
	HEADING="$(gettext 'Mass tagger')"
	IMG='info'
	FRAME="$(gettext 'info')"
	echo "$(gettext "This will edit the meta information of ALL supported tracks in the chosen list. Untouched tags will NOT be removed. This means you can add one of the tags to all your files without removing the others.

Middle-click on file to remove it from the list.

For advanced tagging you can use shell commands instead of static text in the fields. This is very useful to track-titles which almost never will be equal to another one.
Some examples:

Filename is 'artist - title.mp3'.
Command to grab title will be:")" > $WORKDIR/masstagger_info
	echo -e "<span fgcolor='"'darkgreen'"'><i>exe:echo 'FILENAME' | awk -F ' - ' '{print \\\$2}'</i></span>\n" >> $WORKDIR/masstagger_info

	echo "$(gettext "Album might be the name of the directory:")" >> $WORKDIR/masstagger_info
	echo -e "<span fgcolor='"'darkgreen'"'><i>exe:echo 'DIRNAME'</i></span>\n" >> $WORKDIR/masstagger_info

	echo "$(gettext "Track-title in an e-book could be named like this:")" >> $WORKDIR/masstagger_info
	echo -e "<span fgcolor='"'darkgreen'"'><i>exe:echo 'Mybook chapter '"'\$(printf "%02d" COUNT)'"</i></span>\n" >> $WORKDIR/masstagger_info

	echo "$(gettext "To clear a chosen tag, use the builtin command:")" >> $WORKDIR/masstagger_info
	echo -e "<span fgcolor='"'darkgreen'"'><i>exe:CLEAR</i></span>\n" >> $WORKDIR/masstagger_info

	echo "$(gettext "And then the rules:
- Line must start with exe:
- Builtin variables are FILENAME, DIRNAME and COUNT
- Builtin command is CLEAR
- Never use \"
- Place a \\ in front of \$")" >> $WORKDIR/masstagger_info

	TXT1="$(<$WORKDIR/masstagger_info)"
	. $APPDIR/box_ok &
}


set_albumart (){
	TITLE="- $(gettext 'Define albumart sourcefile')"
	CHOOSER_DIR="$STORAGE_DIR/albumart/"
	. $APPDIR/box_chooser
	if [ "$EXIT" = "OK" ]; then
		if [ -f "$CHOOSER" ] && [ "`grep -iE "\.jpg$|\.png$|\.gif$" <<< "$CHOOSER"`" ]; then
			rm $WORKDIR/tmp_masstagger_albumart.jpg
			cp "$CHOOSER" $WORKDIR/tmp_masstagger_albumart.jpg
		else
			TXT1="<b>$(gettext 'No valid image file')</b> (jpg/png/gif)"
			TXT2="$CHOOSER"
			. $APPDIR/box_ok
		fi
	fi
}

fetch_dir (){
	TITLE="- $(gettext 'Add file(s) to list')"
	XML_CHOOSER='
	<hseparator></hseparator>
	<checkbox>
	 <variable>CHK_RECURSIVE</variable>
	 <label>"'$(gettext 'Add recursively (also add files from sub-directories)')'"</label>
	</checkbox>'
	. $APPDIR/box_chooser
	case $(file "$CHOOSER") in
		*directory*)
			if [ $CHK_RECURSIVE = true ]; then
				find "$CHOOSER" | grep -E "$AUDIO_FORMATS" >> $WORKDIR/id3tagger
			else
				find "$CHOOSER" -mindepth 1 -maxdepth 1 -printf "%p\n" | grep -E "$AUDIO_FORMATS" >> $WORKDIR/id3tagger
			fi
			;;
		*)
			echo "$CHOOSER" >> $WORKDIR/id3tagger
			;;
	esac
}

filelist_release_event (){
	if [[ $BUTTON = 2 && "$TAG_FILES" ]]; then
			grep -v "$TAG_FILES" $WORKDIR/id3tagger > $WORKDIR/tmp_id3tagger
			mv -f $WORKDIR/tmp_id3tagger $WORKDIR/id3tagger
	fi
}

export -f info set_albumart fetch_dir filelist_release_event

cp $HOME/.pmusic/nowplaying_albumart.jpg $WORKDIR/tmp_masstagger_albumart.jpg
$APPDIR/func_svg -heading "$(gettext 'Mass tagger')"

echo '
<window title="pMusic - '$(gettext 'Mass tagger')'" icon-name="pmusic" default_width="470" default_height="400">
<vbox '$ST'>
 <vbox '$SF'>
  <hbox spacing="0" height="75" scrollable="true" '$ST' vscrollbar-policy="2" hscrollbar-policy="2">
   <eventbox name="svgheading" '$ST'>
    <hbox '$ST'>
     <text width-request="20" '$SF'><label>""</label></text>
     <text ypad="45" use-markup="true" '$SF'><label>"<i>'$(gettext 'Tag all files in the list in one operation.')' <b>'$(gettext 'Check info.')'</b></i>"</label></text>
     <text '$ST'><label>""</label></text>
     <hbox spacing="0" '$SF'>
      <vbox>
       <button relief="2" can-focus="false" '$SF'>
        <input file stock="gtk-help"></input>
        <action>info > /dev/null &</action>
       </button>
       <text '$ST'><label>""</label></text>
      </vbox>
     </hbox>
    </hbox>
   </eventbox>
  </hbox>
 </vbox>

 <hbox '$ST'>
  <vbox '$ST'>
    <vbox spacing="0" '$ST'>
     <eventbox name="alt_list_header" '$SF'>
      <hbox spacing="0" '$ST'>
      <button relief="2" name="alt_list_header" width-request="50" '$ST'>
       <input file stock="gtk-open"></input>
       <action>fetch_dir</action>
       <action>refresh:TAG_FILES</action>
      </button>
      <button relief="2" name="alt_list_header" tooltip-text="'$(gettext 'Fetch tracks from Playqueue')'" '$ST'>
       <input file stock="gtk-import"></input>
       <label>" '$(gettext 'PlayQueue')'"</label>
       <action>cut -d"|" -f4 '$WORKDIR'/playlist >> '$WORKDIR'/id3tagger</action>
       <action>refresh:TAG_FILES</action>
      </button>
      <button relief="2" name="alt_list_header" tooltip-text="'$(gettext 'Fetch tracks from Sourcelist')'" '$ST'>
       <input file stock="gtk-import"></input>
       <label>" '$(gettext 'Sourcelist')'"</label>
       <action>cut -d"|" -f14 '$WORKDIR'/sourcelist | grep -E "'$AUDIO_FORMATS'" >> '$WORKDIR'/id3tagger</action>
       <action>refresh:TAG_FILES</action>
      </button>
      <button relief="2" name="alt_list_header" width-request="50" tooltip-markup="'$(gettext 'Clear list.
To remove <b>one</b> item from list, use mouse middle-click.')'" '$ST'>
       <input file stock="gtk-pmusic_clear"></input>
       <action>echo -n > '$WORKDIR'/id3tagger</action>
       <action>refresh:TAG_FILES</action>
      </button>
     </hbox>
     </eventbox>
     <hbox '$ST'>
      <tree stock-id="gtk-audio" file-monitor="true" auto-refresh="true" headers-visible="false" hover-selection="true" '$ST'>
       <variable>TAG_FILES</variable>
       <input file>'$WORKDIR'/id3tagger</input>
       <output file>'$WORKDIR'/id3tagger</output>
       <action signal="button-release-event">filelist_release_event</action>
       <action signal="button-release-event">refresh:TAG_FILES</action>
      </tree>
     </hbox>
    </vbox>
  </vbox>
  <vbox '$ST'>
   <vbox '$SF'>
    <hbox>
     <text width-request="100" use-markup="true"><label>" <b>'$(gettext 'Artist')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear" >
      <variable>GUI_ARTIST</variable><default>"'$ARTIST'"</default>
      <action signal="primary-icon-release">clear:GUI_ARTIST</action>
     </entry>
    </hbox>
    <hbox>
     <text width-request="100" use-markup="true"><label>" <b>'$(gettext 'Title')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear" >
      <variable>GUI_TITLE</variable>
      <action signal="primary-icon-release">clear:GUI_TITLE</action>
     </entry>
    </hbox>
    <hbox>
     <text width-request="100" use-markup="true"><label>" <b>'$(gettext 'Album')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear" >
      <variable>GUI_ALBUM</variable>
      <default>"'$ALBUM'"</default>
      <action signal="primary-icon-release">clear:GUI_ALBUM</action>
     </entry>
    </hbox>
    <hbox>
     <text width-request="100" use-markup="true"><label>" <b>'$(gettext 'Year')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear">
      <variable>GUI_YEAR</variable>
      <default>"'$YEAR'"</default>
      <action signal="primary-icon-release">clear:GUI_YEAR</action>
     </entry>
    </hbox>
    <hbox spacing="0">
     <text width-request="105" use-markup="true"><label>" <b>'$(gettext 'Track nr')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear" >
      <variable>GUI_NR</variable>
      <input file>'$WORKDIR'/tmp_id3tagger_track</input>
      <action signal="primary-icon-release">echo "" > '$WORKDIR'/tmp_id3tagger_track</action>
      <action signal="primary-icon-release">refresh:GUI_NR</action>
     </entry>
     <button width-request="27" height-request="27">
      <input file stock="gtk-go-back"></input>
      <action>echo "exe:printf \"%01d\" COUNT" > '$WORKDIR'/tmp_id3tagger_track</action>
      <action>refresh:GUI_NR</action>
      <action>rm '$WORKDIR'/tmp_id3tagger_track</action>
     </button>
    </hbox>
    <hbox>
     <text width-request="100" use-markup="true"><label>" <b>'$(gettext 'Comment')'</b>"</label></text>
     <entry primary-icon-stock="gtk-clear">
      <variable>GUI_COMMENT</variable>
      <action signal="primary-icon-release">clear:GUI_COMMENT</action>
     </entry>
    </hbox>
    <hbox>
     <text '$SF' use-markup="true"><label>" <b>'$(gettext 'Genre')'</b>"</label></text>
     <hbox '$ST'>
      <text><label>""</label></text>
     </hbox>
     <comboboxentry><variable>GUI_GENRE</variable><default>"'$GENRE'"</default>'$ID3_GENRES'</comboboxentry>
    </hbox>
   </vbox>
   <vbox '$ST'>
    <hseparator height-request="20"></hseparator>
   </vbox>
   <vbox '$SF'>
    <hbox>
     <text '$SF' width-request="10"><label>""</label></text>
     <vbox>
      <hbox '$SF'>
      <button '$SF'>
       <variable>SET_ALBUMART</variable>
       <input file stock="gtk-open"></input>
       <label>'$(gettext 'Another image')'</label>
       <sensitive>false</sensitive>
       <action>set_albumart</action>
       <action>refresh:PIC_ALBUMART</action>
      </button>
      </hbox>
      <text '$ST'><label>""</label></text>
      <checkbox>
       <variable>ALBUMART</variable>
       <label>'$(gettext 'Embed image to ALL files')'</label>
       <action>if true enable:PIC_ALBUMART</action>
       <action>if true enable:SET_ALBUMART</action>
       <action>if false disable:PIC_ALBUMART</action>
       <action>if false disable:SET_ALBUMART</action>
      </checkbox>
     </vbox>
     <pixmap '$SF'>
      <width>100</width>
      <height>100</height>
      <variable>PIC_ALBUMART</variable>
      <input file>'$WORKDIR'/tmp_masstagger_albumart.jpg</input>
      <sensitive>false</sensitive>
     </pixmap>
    </hbox>
    <hseparator></hseparator>
   </vbox>
  </vbox>
 </hbox>
 <hbox '$SF'>
  <timer visible="false"><action>refresh:ID3_STATUSBAR</action></timer>
  <statusbar has-resize-grip="false" '$ST'>
   <variable>ID3_STATUSBAR</variable>
   <input>echo " $(cat '$WORKDIR'/id3tagger | wc -l) '$(gettext 'files added to list')'"</input>
  </statusbar>
  <button '$SF'>
   <label>'$(gettext 'Clear tags')'</label>
   <input file stock="gtk-clear"></input>
   <action>save:TAG_FILES</action>
   <action type="exit">clear_tag</action>
  </button>
  <hbox spacing="0">
   <button name="highlight" '$SF'>
    <label>'$(gettext 'Save tags')'</label>
    <input file stock="gtk-save"></input>
    <action>save:TAG_FILES</action>
    <action type="exit">save</action>
   </button>
   <statusbar width-request="22"></statusbar>
  </hbox>
 </hbox>
</vbox>
</window>' > $WORKDIR/xml_pmusic_id3tagger
[ $TOOLTIPS = false ] && sed -i 's%tooltip-%tooltipXXX%g' $WORKDIR/xml_pmusic_id3tagger #deactivate tooltips
IFS=""
for STATEMENTS in $($GTKDIALOG -f $WORKDIR/xml_pmusic_id3tagger); do
	eval $STATEMENTS
done

case $EXIT in Cancel|abort|'') exit;; esac
RETVAL="$EXIT"

#msg: no files defined
if [ ! -s $WORKDIR/id3tagger ]; then
	TXT1="$(gettext 'No files is defined. Nothing to do.')"
	. $APPDIR/box_ok
	exit
fi
#msg: do you really want to clear all tags
if [ "$EXIT" = "clear_tag" ]; then
	FRAME="$(gettext 'Clear tags')"; IMG="question"
	TXT1="$(gettext 'Do you really want to clear the tags for ALL files in the list?
Be aware that this also removes any embedded albumart.')"
	. $APPDIR/box_yesno
	[ $EXIT != "yes" ] && exit
fi

#show splash
gettext 'Tagging files...' > $WORKDIR/splashtext
$APPDIR/box_splash progress &

echo '#!/bin/bash' > $WORKDIR/exec_masstagger
[ $UTF8 != true ] && echo 'LC_ALL=C' >> $WORKDIR/exec_masstagger

COUNT=0
TOTAL=`grep -c ^ $WORKDIR/id3tagger`
echo -n > $WORKDIR/tmp_id3db

while read FILE; do
	FILE=${FILE##*|}
	[[ "$FILE" != */* ]] && continue
	#update progressbar
	echo $(($COUNT*100/$TOTAL)) > $WORKDIR/splash 
	COUNT=$(($COUNT+1))
	#Variables used in exe: ... COUNT might also be used
	FILENAME=${FILE##*/} #basename
	FILENAME=${FILENAME%.*} #file
	FILENAME=${FILENAME//\'/\'\\\'\'} #handle '
	FILENAME=${FILENAME//&/\\&} #handle &
	DIRNAME=${FILE%/*}
	DIRNAME=${DIRNAME##*/}
	#define if we shall use value from gui or exiting
	. $APPDIR/func_id3io "$FILE" -read
	[ "$GUI_ARTIST" ]	&& ARTIST="$GUI_ARTIST"
	[ "$GUI_TITLE" ]	&& TITLE="$GUI_TITLE"
	[ "$GUI_ALBUM" ]	&& ALBUM="$GUI_ALBUM"
	[ "$GUI_YEAR" ]		&& YEAR="$GUI_YEAR"
	[ "$GUI_NR" ]		&& NR="$GUI_NR"
	[ "$GUI_GENRE" ]	&& GENRE="$GUI_GENRE"
	[ "$GUI_COMMENT" ]	&& COMMENT="$GUI_COMMENT"
	#check for internal commands
	echo -n > $WORKDIR/exec_tagging
	chmod 722 $WORKDIR/exec_tagging
	case $ARTIST in
		exe:CLEAR*) ARTIST='';;
		exe:*)
			T=${ARTIST#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			ARTIST="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $TITLE in
		exe:CLEAR*) TITLE='';;
		exe:*)
			T=${TITLE#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			TITLE="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $ALBUM in
		exe:CLEAR*) ALBUM='';;
		exe:*)
			T=${ALBUM#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			ALBUM="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $YEAR in
		exe:CLEAR*) YEAR='';;
		exe:*)
			T=${YEAR#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			YEAR="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $NR in
		exe:CLEAR*) NR='';;
		exe:*)
			T=${NR#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			NR="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $GENRE in
		exe:CLEAR*) GENRE='';;
		exe:*)
			T=${GENRE#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			GENRE="`$WORKDIR/exec_tagging`"
			;;
		*\([0-9]*)
			#convert genre number to something human readable. See $APPDIR/txt_id3genre
			TMP="`echo "$GENRE" | cut -d'(' -f2 | cut -d')' -f1`"
			if [[ "$TMP" && "$TMP" -lt "300" ]]; then
				TMP=$((10#${TMP})) #remove leading 0
				GENRE="`grep -F "(${TMP})" $APPDIR/txt_id3genre`"
				GENRE=${GENRE%(*}
			fi
			;;
	esac
	case $COMMENT in
		exe:CLEAR*) COMMENT='';;
		exe:*)
			T=${COMMENT#*:}; T=${T//FILENAME/$FILENAME}; T=${T//DIRNAME/$DIRNAME}
			echo "${T//COUNT/$COUNT}" > $WORKDIR/exec_tagging
			COMMENT="`$WORKDIR/exec_tagging`"
			;;
	esac
	case $RETVAL in
		save)
			[ "$ALBUMART" = true ] && I_ALBUMART="-i $WORKDIR/tmp_masstagger_albumart.jpg" 
			. $APPDIR/func_id3io "$FILE" -write_no_update
			;;
		clear_tag)
			. $APPDIR/func_id3io "$FILE" -clear_no_update
			;;
	esac

done < $WORKDIR/id3tagger

$APPDIR/func_index -merge_stack &
sleep 0.3
chmod 722 $WORKDIR/exec_id3io_post
$WORKDIR/exec_id3io_post
echo -n > $WORKDIR/exec_id3io_post

#---
echo 100 > $WORKDIR/splash
echo -n > $WORKDIR/id3tagger
